import React from 'react';
import { message, notification } from 'antd';
import {
  Form
} from 'antd';
import Error from '../Error';
import InnerForm from './InnerForm.js';
import InnerTable from './InnerTable.js';
import InnerPagination from './InnerPagination.js';
import './index.less';
import globalConfig from 'config.js';
import ajax from '../../utils/ajax';
import Logger from '../../utils/Logger';
const logger = Logger.getLogger('DBTable');

/**
 * 操作数据库中的一张表的组件, 又可以分为3个组件: 表单+表格+分页器
 */
class DBTable extends React.Component {

  // 代替componentWillMount
  constructor(props) {
    super(props);

    this.tableConfig = {
      showQueryFrom: true, //显示查询表单
      showSearchBtn: true, //显示查询按钮
      showExport: true,  // 显示导出按钮, 默认true
      showImport: true,  // 显示导入按钮, 默认true
    }

    // 组件初始化时尝试获取schema
    this.tryFetchSchema(this.props);
  }

  // 父组件要保存子组件的状态...非常蛋疼...
  // 破坏了子组件的"封闭"原则

  // 注意: 向父组件传状态, 通过回调函数的形式
  // 从父组件接收状态, 通过props的形式

  state = {
    lookwatch:"",
    queryName: "querySchema",
    // 表单组件的状态
    queryObj: {},  // 表单中的查询条件
    moduleName: '', //模块名称
    // 表格组件的状态
    data: [],  // 表格中显示的数据
    tableLoading: false,  // 表格是否是loading状态

    // 分页器的状态
    currentPage: 1,  // 当前第几页
    pageSize: 10,  // pageSize暂时不可修改, 固定50
    total: 0,  // 总共有多少条数据
    tableName: '', //表名
    requestParams: (this.props.requestParams ? this.props.requestParams : {}),
    query: [],     //通过InnerTable获得InnerForm中的数据,
    lookForm:[],
    look:""
  };

  /**
   * 尝试获取某个表的querySchema和dataSchema
   * 无论是从远端获取还是从本地配置读取, 这个方法必须是同步的
   *
   * @param dbName
   * @param tableName
   */
  tryFetchSchema(props) {
    var routes;

    if (props.routes == undefined) {
      routes = props;
    }
    else {
      routes = props.routes.pop();
    }

    // 这个tableName是路由表配置中传过来的
    // 可以用这个方法向组件传值
    const tableName = routes.tableName.toLowerCase();
    {
      if (routes.tableName) {
        this.state.moduleName = routes.tableName;
      }
      if (routes.queryName) {
        this.state.queryName = routes.queryName;
      }
    }
    if (tableName) {
      logger.info('init component DBTable with tableName = %s', tableName);
    } else {
      logger.error('can not find tableName, check your router config');
      this.inited = false;  // 是否成功获取schema
      this.errorMsg = '找不到表名, 请检查路由配置';  // 如果没能成功获取schema, 错误信息是什么?
      return;
    }

    // 其实很多这种this.xxx变量也可以做成状态, 看情况了
    // 关键是这些变量变化时, 是否要触发重新render?

    this.state.tableName = tableName;
    const { queryName } = this.state;

    try{
     this.lookForm = require(`../../schema/${tableName}/lookSchema.js`) 
    }catch(e){
      logger.error(`${tableName},${queryName}`, e);
      this.inited = false;
      this.errorMsg = `加载${tableName}表的lookSchema出错, 请检查配置`;
      return;
    }
    // 尝试加载querySchema
    try {
      this.querySchema = require(`../../schema/${tableName}/${queryName}.js`)
    } catch (e) {
      logger.error(`${tableName},${queryName}`, e);
      this.inited = false;
      this.errorMsg = `加载${tableName}表的${queryName}出错, 请检查配置`;
      return;
    }
    // 尝试加载formSchema
    try {
      this.formSchema = require(`../../schema/${tableName}/formSchema.js`);
    } catch (e) {
      logger.error('load query schema error: %o', e);
      this.inited = false;
      this.errorMsg = `加载${tableName}表的formSchema出错, 请检查配置`;
      return;
    }

    // 尝试加载dataSchema
    try {
      this.dataSchema = require(`../../schema/${tableName}/dataSchema.js`);
    } catch (e) {
      logger.error('load data schema error: %o', e);
      this.inited = false;
      this.errorMsg = `加载${tableName}表的dataSchema出错, 请检查配置`;
      return;
    }

    // 尝试加载个性化配置, 加载失败也没影响
    try {
      var tableConfig = require(`../../schema/${tableName}/config.js`);
      Object.assign(this.tableConfig, tableConfig);
    } catch (e) {
      logger.warn('can not find config for table %s, use default instead', tableName);
    }

    this.inited = true;
  }

  /**
   * 刚进入页面时触发一次查询
   */
  componentDidMount() {
    this.refresh();
  }
 
  // 在react router中切换时, 组件不会重新mount, 只有props会变化
  componentWillReceiveProps = (nextProps) => {
    const params = this.props.requestParams;
    const currentParentId = params ? 
    (params.parentId ? params.parentId : params.catId) : null;
    const nextParentId = nextProps.requestParams ?
    (nextProps.requestParams.parentId ?
    nextProps.requestParams.parentId : nextProps.requestParams.catId ) : null;
    if (!nextParentId || (nextParentId == currentParentId)) {
      return;
    }
    logger.debug('receive new props and try to render, nextProps = %o', nextProps);
    this.tryFetchSchema(nextProps);  // 根据新的props重新获取配置

    this.state.queryObj = {};
    this.state.data = [];
    this.state.tableLoading = false;
    this.state.currentPage = 1;
    this.state.pageSize = 10;
    this.state.total = 0;
    // this.state.requestParams = nextProps.requestParams;
    this.setState({requestParams: nextProps.requestParams}, () => {

      // 切换时也要重新查询一次数据
      this.refresh();
    });
  }

  /**
   * 切换分页时触发查询
   *
   * @param page
   */
  handlePageChange = (page) => {
    logger.debug('handlePageChange, page = %d', page);
    this.setState({ tableLoading: true });
    this.select(this.state.queryObj, page, this.state.pageSize).then((result) => {
      //message.success('查询成功');
      this.setState({
        currentPage: page,
        data: result.data.list,
        total: result.data.total,
        tableLoading: false,
        bottomInfo: result.data.bottomInfo,
      });
    }, this.handleError);
  }

  /**
   * 点击提交按钮时触发查询
   *
   * @param queryObj
   */
  handleFormSubmit = (queryObj) => {
    logger.debug('handleFormSubmit, queryObj = %o', queryObj);
    this.setState({ tableLoading: true });
    // 这时查询条件已经变了, 要从第一页开始查
    this.select(queryObj, 1, this.state.pageSize).then((result) => {
      //message.success('查询成功');
      this.onBeforeRefresh(result);
      this.setState({
        currentPage: 1,
        data: result.data.list,
        total: result.data.total,
        tableLoading: false,
        queryObj: queryObj,
        bottomInfo: result.data.bottomInfo,
      });
    }, this.handleError);
  }

  /**
   * 统一处理ajax失败时的回调
   *
   * @param errorMsg
   */
  handleError = (errorMsg) => {
    // 对于错误信息, 要很明显的提示用户, 这个通知框要用户手动关闭
    notification.error({
      message: '出错啦!',
      description: `请联系管理员, 错误信息: ${errorMsg}`,
      duration: 0,
    });
    this.setState({ tableLoading: false });
  };

  onBeforeRefresh = (result) => {

  }

  /**
   * 按当前的查询条件重新查询一次
   */
  refresh = () => {
    this.setState({ tableLoading: true });
    this.select(this.state.queryObj, this.state.currentPage, this.state.pageSize).then((result) => {
      // message.success('查询成功');
      /**
       * 查询动画结束有一定时间，延时500ms显示成功，让节奏舒适一点
       */
      setTimeout(function () {
        message.success('查询成功');
      }, 500);
      this.onBeforeRefresh(result);

      let pageble = this.tableConfig.pageEnable;
      if (pageble == 0) {
        this.setState({ pageSize: result.data.total });
      }
      this.setState({
        data: result.data.list,
        totalData: result.data,
        total: result.data.total,
        tableLoading: false,
        bottomInfo: result.data.bottomInfo,
      });
    }, this.handleError);
  }

  refreshTree = () => {
    if (this.state.requestParams && this.props.refreshTree) {
      this.props.refreshTree(this.state.requestParams.parentId);
    }

  }

  /**
   * 向服务端发送select请求, 会返回一个promise对象
   *
   * @param queryObj 包含了form中所有的查询条件, 再加上page和pageSize, 后端就能拼成完整的sql
   * @param page
   * @param pageSize
   * @returns {Promise}
   */
  select(queryObj, page, pageSize) {
    const hide = message.loading('正在查询...', 0);
    const that = this;
    // console.log(this.state.tableName)
    var url = this.tableConfig.selectUrl ? `/${this.tableConfig.selectUrl}` : `/${this.state.tableName}/list`;
    let pageble = this.tableConfig.pageEnable;//是否分页参数 为0时不分页,其他时候都分页

    // 只是为了试下ES6的Promise特性...其实直接用superagent的API也可以
    const promise = new Promise((resolve, reject) => {
      let param;
      if (pageble == 0) {
        param = { query: JSON.stringify(queryObj) };
      }
      else {
        param = { pageNum: page, numPerPage: pageSize, query: JSON.stringify(queryObj) };
      }
      Object.assign(param, this.state.requestParams);
      //向属性中添加this.props.params中的属性
      Object.assign(param, this.props.params);
      // console.log('url',url)
      ajax.post({
        url: url,
        params: param,
        success: function (result) {
          hide();
          that.checkResult(result);
          result = that.handleResult(result);
      console.log('result',result)
          
          resolve(result);
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            // 通常 textStatus 和 errorThrown 之中
            // 只有一个会包含信息
             setTimeout(() => {
              hide();
              that.setState({tableLoading: false,});
              message.error(`查询失败,错误${XMLHttpRequest.status}...`);
            },500);
        },
      })
    })

    return promise;
  }

  checkResult = (result) => {
    if(!!!result.data){
      this.setState({tableLoading: false,});
      setTimeout(() => {
        message.error('格式错误，没有data');
      }, 500);
      throw new Error('格式错误，没有data');
    }
  }

  handleResult = (result) => {
    return result;
  }

  createInnerTable() {
    return InnerTable;
  }

  createInnerForm() {
    return InnerForm;
  }

  getChildFormData = (obj) => {
  }
  componentshouldupdate(){
    return true
  }

  looks = (event) =>{
      this.lookForm.forEach((item)=>{  
        console.log('item', item) 
        for(let item_two in event){
          if(item.key === item_two){
            if(item.render){
              item.data = item.render(event[item_two], event);
            }else {
              item.data = event[item_two]
            }
            break;
          }else{
            if(item.key !=='files'){
              // console.log(1)
              item.data = "无"
              continue;
            }else{
              item.data = ""
            }
          }
        }   
      })
      
      let lookForm = this.lookForm;
      console.log(lookForm)
      this.setState({
        lookwatch:lookForm
      })
  }

  getInnerTable() {
      if (this.innerFromTable == null) {
        this.innerFromTable = Form.create()(this.createInnerTable());
      }
      const InnerFromTable = this.innerFromTable;
      return (<InnerFromTable requestParams={this.state.requestParams} data={this.state.data} tableLoading={this.state.tableLoading}
        schema={this.dataSchema} refresh={this.refresh} refreshTree={this.refreshTree}
        moduleName={this.state.moduleName}
        formSchema={this.formSchema}
        totalData={this.state.totalData}
        bottomInfo={this.state.bottomInfo}
        query={this.state.query} rowKey={this.props.rowKey}
        tableConfig={this.tableConfig} tableName={this.state.tableName} lookForm={this.lookForm} look={this.looks}/>);     
  }

  getInnerForm() {
    let form = null;
    if (this.tableConfig.showQueryFrom) {
      if (this.InnerNewFrom == null) {
        this.InnerNewFrom = Form.create({ onFieldsChange: this.getFormData })(this.createInnerForm());
      }
      const InnerNewFrom = this.InnerNewFrom;
      form = (<InnerNewFrom ref="getInnerFormData" requestParams={this.state.requestParams} parentHandleSubmit={this.handleFormSubmit} schema={this.querySchema} tableConfig={this.tableConfig}
        totalData={this.state.totalData} tableName={this.state.tableName} />);
    }
    return form;
  }

  getFormData = (props, fields) => {
    let myInnerForm = this.refs.getInnerFormData;
    let oldObj = myInnerForm.getFieldsValue();
    let newObj = {};
    for (const key in oldObj) {
      if (oldObj[key]) {
        if (oldObj[key] instanceof Object) {
          if(!!oldObj[key][1]) {
            newObj[`${key}Begin`] = oldObj[key][0].format('YYYY-MM-DD  HH:mm:ss');
            newObj[`${key}End`] = oldObj[key][1].format('YYYY-MM-DD  HH:mm:ss');
          }else {
            newObj[key] = oldObj[key].format('YYYY-MM-DD');
          }
        } else {
          newObj[key] = oldObj[key];
        }
      }
    }

    this.setState({ query: newObj });
  }

  render() {
    // 如果没能成功加载schema, 显示错误信息
    if (!this.inited) {
      return (
        <Error errorMsg={this.errorMsg} />
      );
    }

    return (
      <div>
        {this.getInnerForm()}
        {this.getInnerTable()}
        {!!this.state.total && <InnerPagination currentPage={this.state.currentPage} total={this.state.total} pageSize={this.state.pageSize}
          parentHandlePageChange={this.handlePageChange} tableConfig={this.tableConfig}
          tableName={this.state.tableName} />}
      </div>
    );
  }

}

export default DBTable;
